﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace DenisVuyka.Controls.PropertyGrid
{
  /// <summary>
  /// Provides additional facilities for TextBox control.
  /// http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/564b5731-af8a-49bf-b297-6d179615819f/
  /// </summary>
  public class TextBoxExtender
  {
    /// <summary>
    /// Identifies the <see cref="SelectAllOnFocus"/> attached property.
    /// </summary>
    public static readonly DependencyProperty SelectAllOnFocusProperty =
      DependencyProperty.RegisterAttached("SelectAllOnFocus", typeof(bool), typeof(TextBoxExtender),
      new FrameworkPropertyMetadata(false, OnSelectAllOnFocusChanged));
        
    public static void SetSelectAllOnFocus(DependencyObject target, bool value)
    {
      target.SetValue(SelectAllOnFocusProperty, value);
    }

    public static bool GetSelectAllOnFocus(DependencyObject target)
    {
      return (bool)target.GetValue(SelectAllOnFocusProperty);
    }
    
    private static void OnSelectAllOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      TextBox box = d as TextBox;

      if (box == null) return;

      bool wasBound = (bool)(e.OldValue);
      bool needToBind = (bool)(e.NewValue);

      if (wasBound)
        UnhookEvents(box);

      if (needToBind)
        HookEvents(box);
    }

    static void HookEvents(TextBox box)
    {
      box.MouseDoubleClick += HandleGotFocus;
      box.GotKeyboardFocus += HandleGotFocus;
      box.PreviewMouseLeftButtonDown += SelectivelyIgnoreMouseButton;
    }

    static void UnhookEvents(TextBox box)
    {
      box.MouseDoubleClick -= HandleGotFocus;
      box.GotKeyboardFocus -= HandleGotFocus;
      box.PreviewMouseLeftButtonDown -= SelectivelyIgnoreMouseButton;
    }

    static void HandleGotFocus(object sender, RoutedEventArgs e)
    {
      TextBox tb = (sender as TextBox);
      if (tb != null)
        tb.SelectAll();
    }

    static void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
      TextBox tb = (sender as TextBox);

      if (tb != null)
      {
        if (!tb.IsKeyboardFocusWithin)
        {
          e.Handled = true;
          tb.Focus();
        }
      }
    }
  }
}
